JavaScript 基础篇之注意点


一、定义函数的方式

定义函数的方式有两种,分别是:函数声明与函数表达式
函数声明:

1
2
3
function fun1(a,b,c) {
//函数体
}

函数表达式:

1
2
3
var fun2 = function(a,b,c){
//函数体
};

这两种方法有什么区别呢?
1、函数声明提升
函数声明的一个重要特征就是函数声明提升,意思在执行代码前先读取函数声明,如果我在下面的代码中找到了这个函数的,一样会执行这个函数,也就是说我们可以将函数声明放在调用它的后面。

1
2
3
4
a();//Hi!
function a(){
alert("Hi!");
}

这个例子会执行 a() 方法,弹出 Hi!
而使用函数表达式的方式定义函数则不会出现函数声明提升这一种情况并且浏览器会报错

1
2
3
4
b();//Uncaught TypeError: b is not a function
var b = function(){
alert("Hi!");
};

2、name 属性
使用函数声明的方式的函数会拥有一个 name 属性,可以通过这个属性访问到函数的名字,但在 ECMAScript5 使用函数表达式的方式则 name 属性为空字符串,但 ECMAScript6 中这个问题已经解决了,即使使用函数表达式也能够返回 name 的值

3、函数的覆盖
这一点主要体现在用判断语句决定函数的定义的时候,例如:

1
2
3
4
5
6
7
8
9
if(true) {
function sayName(){
alert("Eyesim");
}
}else {
function sayName() {
alert("Gordorn");
}
}

实际上这个在 ECMAScript 中属于无效语法,于是 JavaScript 引擎会尝试对其进行修改,但注意一点是,有些浏览器会将其修改返回第二个函数,但如果用函数表达式的方式声明就不会产生这个问题了。

1
2
3
4
5
6
7
8
9
10
var sayHi;
if(true){
sayHi = function() {
alert("Eyesim");
};
}else {
sayHi = function() {
alert("Gordorn");
};
}

二、窗口大小

innerWidth、outerWidth、clientWidth 这三个的区别是什么?

1.innerWidth 与 outerWidth

在 IE9+、Chrome、Opera、Firefox 与 Safari 中的 innerWidth 与 outerWidth 的定义是不一样的:

IE9+、Firefox 与 Safari: outerWidth 返回的是浏览器窗口本身的尺寸

Opera: outerWidth 表示的是页面视图容器的大小,而 innerWidth 则表示表示页面视图的大小(即减去边框宽度)

Chrome: innerWidth 和 outerWidth 返回的是 viewport 大小

2.clientWidth

具体可参考我的另一篇博文

三、Boolean 对象与 Boolean 值在 if()转换中的区别

我们来看一下例子:

1
2
3
4
5
6
7
8
var x = new Boolean();
if(x) {
alert("hi");
}
var y = Boolean(0);
if(y) {
alert("hello");
}

猜一下代码上面显示的结果是什么?hi?hello?hi hello?还是不显示?
答案是:hi。
实际上,x 为 Boolean 对象,在 if 语句中的判断为 true,虽然 x 的值为 false ,但在布尔表达式式中,所有的对象都会被转换为 true ,y 就不用说了,值为 false,所以上面的结果为 hi。

四、parseInt 数值转换

1
2
3
var a = parseInt(0x10),
b = parseInt(10);
console.log(a,b);

猜一下上面 a 与 b 输出的结果是什么?

  • 10 10?
  • 0 10?
  • 16 10?
  • NAN NAN?
  • 报错?

实际上输出为: 16 10.
parseInt(a,b) 有两个参数:

  • a 是你要转换的数值或字符
  • b 是你要转换的进制,一般 b 没填会默认为十进制。

注意点(不填第二个参数的情况下):

  1. 当 a 为数值时非字符串:
  • 0x 开头会被默认为十六进制解析
  • 0 开头会被默认为八进制解析
  • 其它数字开头均当以十进制解析
1
2
3
4
5
var a = parseInt(010),
b = parseInt(0x10),
c = parseInt(10),
d = parseInt(10..222);
console.log(a,b,c,d);//8 16 10 10

2.当 a 为字符串:

  • 0x 开头默认为十六进制
  • 0 开头会默认为十进制
  • 数字开头提取未遇到非数字的字符前的数字转换为十进制
  • 字符开头会转成 NAN
    1
    2
    3
    4
    5
    6
    7
    var a = parseInt('010'),
    b = parseInt('0x10'),
    c = parseInt('10'),
    d = parseInt('10.222'),
    e = parseInt('10xd'),
    f = parseInt('x10');
    console.log(a,b,c,d,e,f);//10 16 10 10 10 NaN

另外提一下 parseFloat 针对字符串的转换只会当成十进制来转换。

1
console.log(parseFloat("0x10"));//0

五、数值精确度

1
2
3
var a = 1 + 2,
b = 0.1 + 0.2;
console.log(a,b);

猜一下 a 与 b 输出是什么?

3 0.3? 当然没那么简单,要不我也不会问了。答案是:3 0.30000000000000004
为什么?这不是 JavaScript 才有的问题,与 JS 语言本身无关,是因为计算机是用二进制来表示浮点数的,无法准确表示一个浮点数,只能逼近。